package com.fan.utils;

import cn.hutool.crypto.digest.MD5;
import org.apache.commons.lang3.StringUtils;

import java.util.Base64;

public class CipherUtil {

    public static final String START_ENCRYPTED_DATA = "ENC(";
    public static final String END_ENCRYPTED_DATA = ")";


    /**
     * 前置信息：开通加解密服务
     * SM4对称加密，用于机密性保护
     * @param plainText 要加密的数据原文
     * @return 密文
     */
    public static String symmetricEncrypt(String plainText) {

        // 已经加密了的数据
        if (plainText.startsWith(START_ENCRYPTED_DATA) && plainText.endsWith(END_ENCRYPTED_DATA)) {
            return plainText;
        }

        Base64.Encoder encoder = Base64.getEncoder();
        byte[] decode = encoder.encode(plainText.getBytes());
        String encryptByPublic = new String(decode);
//        System.out.println("加密后的数据\t" + encryptByPublic);
        return START_ENCRYPTED_DATA + encryptByPublic + END_ENCRYPTED_DATA;

    }

    /**
     * 前置信息：开通加解密服务
     * SM4对称解密
     * @param cipherText 要解密的密文数据
     * @return 原文
     */
    public static String symmetricDecrypt(String cipherText) {
        try {
            if(StringUtils.isBlank(cipherText) || !cipherText.startsWith(START_ENCRYPTED_DATA)){
                return cipherText;
            }

            cipherText = cipherText.substring(START_ENCRYPTED_DATA.length()).substring(0, cipherText.length()-START_ENCRYPTED_DATA.length()-1);

            Base64.Decoder decoder = Base64.getDecoder();

            byte[] decode = decoder.decode(cipherText.getBytes());
            String decryptByPrivate = new String(decode);
//            System.out.println("解密后的数据\t" + decryptByPrivate);
            return decryptByPrivate;
        }catch (Exception e){
            // 为兼容性考虑，返回原文
            return cipherText;
        }

    }

    /**
     * 使用hmac算法生成完整性校验数据。
     * @param plainText 原文数据
     * @return hmac
     */
    public static String hmac(String plainText) {
//         Md5加密
        return MD5.create().digestHex(plainText);
    }

    /**
     * 使用hmac算法进行完整性校验。
     * @param plainText 原文数据
     * @param hmac hmac结果
     * @return 是否验证通过
     */
    public static boolean hmacVerify(String plainText, String hmac) {
        if(StringUtils.isBlank(hmac)){
            return true;
        }

        return MD5.create().digestHex(plainText).equals(hmac);
    }

    public static void main(String[] args) {
//        for (int i = 0; i < 300; i++) {
//            System.out.println("正在进行第 " + (i + 1) + " 次加解密测试");
            String testData = "有人在河边钓鱼";

            // 加密操作
            String cipherData = symmetricEncrypt(testData);
            System.out.println("加密结果: " + cipherData);

            // 解密操作
            String decryptedData = symmetricDecrypt(cipherData);
            System.out.println("解密结果: " + decryptedData);

            // HMAC生成(摘要计算)
            String hmac = hmac(testData);
            System.out.println("HMAC结果: " + hmac);

            // HMAC验证(摘要计算验证)
            boolean verifyResult = hmacVerify(testData, hmac);
            System.out.println("HMAC验证结果: " + verifyResult);
            System.out.println("----------------------------------");
//        }
    }
}